package accesoBD;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * Clase encargada de gestionar la conexión a la base de datos y enviar las consultas.
 * @version 1.2
 * @author Juan Manuel Rodríguez González
 */
public class DataBaseQuery {
    private static String fichero, conexion, url, usuario, pass;
    private Connection con;

    /**
     * Constructor para la clase encargada de gestionar la conexión con la base de datos.
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    public DataBaseQuery() throws SQLException, ClassNotFoundException {
        fichero = "../propiedades/conexionBD.properties";
        configurar();
        con = conectar();
    }

    /**
     * @return Connection Conexion con la base de datos
     * @throws SQLException 
     */
    private static Connection conectar() throws SQLException {
        DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
        Connection con = DriverManager.getConnection(conexion + "@" + url, usuario, pass);
        return con;
    }

    /**
     * Método interno para configurar los parámetros de conexión a la base de datos.
     */
    private static void configurar() {
        Properties prop = new Properties();
        InputStream is = null;
        try {
            String curDir = System.getProperty("user.dir");
            curDir += "/src/incidencias/";
            is = new FileInputStream(curDir + fichero);
            prop.load(is);
        } catch (IOException ioe) {
        }

        //Lectura de propiedades el objeto Properties
        conexion = prop.getProperty("conexion");
        url = prop.getProperty("url");
        usuario = prop.getProperty("usuario");
        pass = prop.getProperty("password");

    }
    
    /**
     * Devuelve el objeto que representa la conexión.
     * @return El objeto de tipo Connection que contiene.
     */
    protected Connection getCon() {
        return con;
    }
    
    /**
     * Método para ejecutar una consulta select.
     * @param consulta String con la sentencia sql que se desea ejecutar.
     * @return El objeto de tipo ResultSet con la salida que se obtiene al ejecutar la consulta.
     * @throws SQLException
     */
    protected ResultSet selectEscrito(String consulta) throws SQLException {
        ResultSet rs;
        Statement stmt;
        con.prepareCall(consulta);
        stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
        rs = stmt.executeQuery(consulta);
        return rs;
    }


    /**
     * Devuelve el número de filas de una consulta.
     * @param res Resultado de ejecutar una cierta consulta.
     * @return El número de filas que contiene la salida de la consulta.
     * @throws SQLException
     */
    private int getNumFilas(ResultSet res) throws SQLException {
        res.last();
        return res.getRow();
    }

    /**
     * Comprueba la existencia de un usuario en la base de datos.
     * @param email Dirección de email del usuario que se desea comprobar.
     * @param password Password del usuario.
     * @return Un objeto GenericQuery instanciado a la subclase específica que 
     * representa al tipo de usuario.
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    public GenericQuery login(String email, String password) throws SQLException, ClassNotFoundException {
        String idUsuario;
        ResultSet res;
        int filas;

        res = selectEscrito("select * from usuario where email='"+email+"'");
        res.last();
        filas = getNumFilas(res);
  
        if (filas > 0) {
            idUsuario = res.getString("id_usuario");
            if (!res.getString("password").equals(password)) {
                return new QueryError("password incorrecto");
            } else {
                idUsuario = res.getString("id_usuario");
                res = selectEscrito("select * from tecnico where id_usuario="+idUsuario);
                filas = getNumFilas(res);
                if (filas > 0) {
                    return new QueryTecnico(idUsuario);
                }

                res = selectEscrito("select * from supervisor where id_usuario="+idUsuario);
                filas = getNumFilas(res);
                if (filas > 0) {
                    return new QuerySupervisor(idUsuario);
                }

                return new QueryUsuario(idUsuario);
            }
        }

        return new QueryError("usuario inexistente");
    }
}
